<?php

class AbstractList extends Node
{

    protected $typeToLoad = '';
    protected $numPerPage = 10;
    protected $sql = '';
    protected $andWhere = '';
    protected $page;
    protected $orders = array( );
    protected $numPages;
    protected $numItems;

    /**
     * Constructor de la clase.
     * @param string $searchclass Clase de los objetos que se van a representar en la lista
     * @param string $sql Condiciones básicas que debe cumplir la lista
     * @param array $orders Vector con los distintos ordenes que puede desplegar la lista como indices y  con valores a -1, 0 o 1
     */
    function __construct( $searchclass, $numperpage, $sql = '',
            $orders = array(
    ) )
    {
        $this->typeToLoad = $searchclass;
        $this->numPerPage = $numperpage;
        $this->sql = $sql;
        $this->orders = $orders;
    }

    /**
     * Establece la página de la lista que se va a mostrar
     * @param int $p Página
     */
    function setPage( $p )
    {
        if ( $p < 1 ) $p = 1;
        $this->page = ( int ) $p;
    }

    /**
     * Selecciona el índice (dentro del array que se pasa al constructor) del orden que se va a utilizar en la lista
     * @param int $orden Índice de la columna que va a establecer el orden. El índice puede ser negativo si queremos establecer el orden inverso.
     */
    function setOrder( $orders )
    {
        $this->orders = ( int ) $orders;
    }

    function setNumPerPage( $num )
    {
        $this->numPerPage = ( int ) $num;
    }

    /**
     * @access private
     * @param <type> $total
     */
    function setNumItems( $total )
    {
        $this->numItems = ( int ) $total;
    }

    /**
     * Método auxiliar para añadir contenido al where. se llamará desde los setWhere correspondientes
     * @param <type> $where cadena sql concondicion
     */
    protected function andWhere( $where )
    { //este no es el where del constructor sino un where a mayores
        if ( !empty( $where ) ) {
            if ( empty( $this->andWhere ) )
                    $this->andWhere = '(' . $where . ')';
            else $this->andWhere.=' AND (' . $where . ')';
        }
    }

    // protected function setWhere(){ //En luegar del fill reescribiremos esté me´todo
    // }

    /**
     * Definimos el método evalue para que actualice la lista después de los métodos que ha recibido
     * @return boolean
     */
    function fill()
    {
        //       $this->setWhere();

        if ( !empty( $this->sql ) && !empty( $this->andWhere ) )
                $sql = $this->sql . ' AND ' . $this->andWhere;
        else $sql = $this->sql . $this->andWhere;

        if ( !empty( $this->numItems ) && $this->page > ceil( $this->numItems / $this->numPerPage ) )
                $this->page = ceil( $this->numItems / $this->numPerPage );

        $eltos = array( );
        $this->_setNumItems(
                Node::getArray( $this->typeToLoad, $eltos, $sql, $this->orders,
                        $this->numPerPage,
                        ($this->page - 1) * $this->numPerPage, $this->numItems )
        );

        if ( $this->numPerPage == 0 ) $this->numPages = 1;
        else if ( $this->numItems == 0 ) $this->numPages = 1;
        else $this->numPages = ceil( $this->numItems / $this->numPerPage );

        if ( $this->page > $this->numPages ) {
            $this->page = $this->numPages;

            $this->_setNumItems(
                    Node::getArray( $this->typeToLoad, $eltos, $sql,
                            $this->orders, $this->numPerPage,
                            ($this->page - 1) * $this->numPerPage )
            );
        }

        foreach ( $eltos as $e ) $this->appendChild( $e );


        return true;
    }

    function handleGET( Event $e )
    {

        switch ( $e->tag ) {
            case 'changePage':
                $this->_setPage( $_REQUEST[ 'page' ] );
                $e->cancelBubble();
                break;

            case 'changeOrder':
                $this->orders[ $_REQUEST[ 'field' ] ] = $_REQUEST[ 'neworder' ];
                //A ver, tengo que comprobar el orden actual y marcar o desmarcar
                $this->_setOrder( $this->orders );
                $e->cancelBubble();
                break;

            case 'changeNumPerPage':
                $this->_setNumPerPage( $_REQUEST[ 'numPerPage' ] );
                $e->cancelBubble();
                break;
        }
    }

}

?>
